home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
libs
/
shutdown.lzh
/
shutdown_5.1
/
src
/
unmount.c
< prev
Wrap
C/C++ Source or Header
|
1996-10-10
|
5KB
|
206 lines
/*
unmount.c --- unmount filesystems.
(c) Copyright 1995 SHW Wabnitz
Written by Bernhard Fastenrath (fasten@shw.com)
This file may be distributed under the terms
of the GNU General Public License.
*/
#include "shutdown_cmd.h"
typedef struct {
struct Message sp_Msg;
struct DosPacket sp_Pkt;
struct Node *sp_Dev;
} MyStandardPacket;
static void
FreeList (List *list)
{
Node *node, *next;
for (next = node = list -> lh_Head; next = node -> ln_Succ; node = next)
{
if (node -> ln_Name)
FreeMem (node -> ln_Name, node -> ln_Pri);
FreeMem (node, sizeof (Node));
}
}
static void
FreeStdPktList (List *list)
{
Node *node, *next;
for (next = node = list -> lh_Head; next = node -> ln_Succ; node = next)
FreeMem (node, sizeof (MyStandardPacket));
}
static int
SendStandardPacket (MsgPort *mp, MyStandardPacket *sp, char *handler, ULONG action, ULONG arg1)
{
DevProc *dp = NULL;
dp = GetDeviceProc (handler, dp);
if (dp)
{
sp -> sp_Pkt.dp_Type = action;
sp -> sp_Pkt.dp_Arg1 = arg1;
SendPkt (&sp -> sp_Pkt, dp -> dvp_Port, mp);
FreeDeviceProc (dp);
return 1;
}
return 0;
}
static int
AllocateStandardPackets (List *pktlist, int count)
{
MyStandardPacket *sp;
int t;
NewList (pktlist);
for (t=0; t<count; t++)
{
if (!(sp = AllocMem (sizeof (MyStandardPacket), MEMF_PUBLIC | MEMF_CLEAR)))
break;
sp -> sp_Msg.mn_Length = sizeof (MyStandardPacket);
sp -> sp_Msg.mn_Node.ln_Name = (char *) &sp -> sp_Pkt;
sp -> sp_Pkt.dp_Link = &sp -> sp_Msg;
AddTail (pktlist, &sp -> sp_Msg.mn_Node);
}
return t;
}
static int
SendToAll (MsgPort *mp, ULONG action, ULONG arg1)
{
int len, count = 0, icount = 0, out_of_mem = 0;
List devlist, pktlist;
MyStandardPacket *sp;
Node *node;
DosList *dl;
char *name;
NewList (&devlist);
NewList (&pktlist);
dl = LockDosList ( LDF_DEVICES | LDF_READ );
while (dl = NextDosEntry (dl, LDF_DEVICES))
{
if (node = (Node *) AllocMem (sizeof (Node), MEMF_CLEAR))
{
name = BADDR (dl -> dol_Name);
len = (int) name[0];
if (node -> ln_Name = AllocMem (len + 2, 0))
{
CopyMem (name+1, node -> ln_Name, len);
node -> ln_Name[len] = ':';
node -> ln_Name[len+1] = '\0';
node -> ln_Pri = len + 2;
AddTail (&devlist, node);
count ++;
}
else
{
out_of_mem = 1;
FreeMem (node, sizeof (Node));
break;
}
}
}
UnLockDosList ( LDF_DEVICES | LDF_READ );
if ((icount = AllocateStandardPackets (&pktlist, count)) == 0)
out_of_mem = 1;
count = icount;
if (out_of_mem)
{
FreeList (&devlist);
return 0;
}
node = devlist.lh_Head;
for (;;)
{
while (node -> ln_Succ)
{
if (sp = (MyStandardPacket *) RemHead (&pktlist))
{
sp -> sp_Dev = node;
SendStandardPacket (mp, sp, node -> ln_Name, ACTION_IS_FILESYSTEM, 0);
icount --;
node = node -> ln_Succ;
}
}
WaitPort (mp);
while (sp = (MyStandardPacket *) GetMsg (mp))
{
icount ++;
if (sp -> sp_Pkt.dp_Type == ACTION_IS_FILESYSTEM &&
sp -> sp_Pkt.dp_Res1 == DOSTRUE)
{
SendStandardPacket (mp, sp, sp -> sp_Dev -> ln_Name, action, arg1);
icount --;
}
else
AddTail (&pktlist, &sp -> sp_Msg.mn_Node);
}
if (!node -> ln_Succ && icount == count)
break;
}
FreeStdPktList (&pktlist);
FreeList (&devlist);
return 1;
}
static int
FsAction (MsgPort *mp, char *filesystem, ULONG action, ULONG arg)
{
#if 0
if (filesystem)
return !SendToHandler (mp, action, filesystem, arg);
else
#endif
return !SendToAll (mp, action, arg);
}
/*** public functions ***/
int
Unmount (char *filesystem, int mode)
{
MsgPort *mp;
int status;
if (!(mp = CreatePort (NULL, 0)))
return 0;
switch (mode)
{
case UMNT_INHIBIT:
status = FsAction (mp, filesystem, ACTION_INHIBIT, DOSTRUE);
break;
case UMNT_READONLY:
status = FsAction (mp, filesystem, ACTION_FLUSH, DOSTRUE);
status |= FsAction (mp, filesystem, ACTION_WRITE_PROTECT, DOSTRUE);
break;
case UMNT_REMOUNT:
/* status = FsAction (mp, filesystem, ACTION_WRITE_PROTECT, DOSFALSE); */
status = FsAction (mp, filesystem, ACTION_INHIBIT, DOSTRUE);
status |= FsAction (mp, filesystem, ACTION_INHIBIT, DOSFALSE);
break;
}
DeletePort (mp);
return !status;
}